package com.eian.boot.module.system.associations.user.post.service;

import com.eian.boot.module.system.associations.user.post.event.UserPostAssignedEvent;
import com.eian.boot.module.system.associations.user.post.mapper.UserPostMapper;
import com.eian.boot.module.system.associations.user.post.model.entity.SysUserPostEntity;
import com.eian.boot.mybatis.core.service.BaseService;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

import static com.eian.boot.table.Tables.sys_user_post;

/**
 * 用户岗位关系管理服务
 * 职责：纯粹的关系数据管理，不包含业务逻辑验证
 *
 * @author alex.meng
 * @since 1.0.0
 */
@Slf4j
@Service
public class UserPostRelationService extends BaseService<UserPostMapper, SysUserPostEntity> {

    private final ApplicationEventPublisher eventPublisher;

    public UserPostRelationService(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    /**
     * 分配用户岗位
     * 先清除旧关系，再建立新关系
     *
     * @param userId  用户ID
     * @param postIds 岗位ID列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void assignUserPosts(Long userId, List<Long> postIds) {
        log.debug("分配用户岗位: userId={}, postIds={}", userId, postIds);

        // 清除旧关系
        this.remove(QueryWrapper.create()
                .from(sys_user_post)
                .where(sys_user_post.user_id.eq(userId)));

        // 建立新关系
        if (postIds != null && !postIds.isEmpty()) {
            List<SysUserPostEntity> relations = postIds.stream()
                    .map(postId -> SysUserPostEntity.builder()
                            .userId(userId)
                            .postId(postId)
                            .build())
                    .collect(Collectors.toList());
            this.saveBatch(relations);
        }

        // 发布领域事件
        eventPublisher.publishEvent(new UserPostAssignedEvent(this, userId, postIds));
    }

    /**
     * 查询用户的岗位ID列表
     *
     * @param userId 用户ID
     * @return 岗位ID列表
     */
    public List<Long> getPostIdsByUserId(Long userId) {
        return this.queryChain()
                .select(sys_user_post.post_id)
                .from(sys_user_post)
                .where(sys_user_post.user_id.eq(userId))
                .listAs(Long.class);
    }

    /**
     * 查询岗位下的用户ID列表
     *
     * @param postId 岗位ID
     * @return 用户ID列表
     */
    public List<Long> getUserIdsByPostId(Long postId) {
        return this.queryChain()
                .select(sys_user_post.user_id)
                .from(sys_user_post)
                .where(sys_user_post.post_id.eq(postId))
                .listAs(Long.class);
    }

    /**
     * 获取岗位关联的用户数量
     *
     * @param postId 岗位ID
     * @return 用户数量
     */
    public long countUsersByPostId(Long postId) {
        return this.queryChain()
                .from(sys_user_post)
                .where(sys_user_post.post_id.eq(postId))
                .count();
    }

    /**
     * 级联删除：当用户被删除时调用
     * 清理用户的所有岗位关系
     *
     * @param userId 用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void cascadeDeleteByUserId(Long userId) {
        log.debug("级联删除用户岗位关系: userId={}", userId);

        this.remove(QueryWrapper.create()
                .from(sys_user_post)
                .where(sys_user_post.user_id.eq(userId)));
    }

    /**
     * 级联删除：当岗位被删除时调用
     * 清理岗位与所有用户的关系
     *
     * @param postId 岗位ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void cascadeDeleteByPostId(Long postId) {
        log.debug("级联删除岗位用户关系: postId={}", postId);

        this.remove(QueryWrapper.create()
                .from(sys_user_post)
                .where(sys_user_post.post_id.eq(postId)));
    }
}

